package com.baizhi.cmfz.config;

import com.baizhi.cmfz.annotation.LogAnnotation;
import com.baizhi.cmfz.entity.CmfzAdmin;
import com.baizhi.cmfz.entity.CmfzLog;
import com.baizhi.cmfz.mapper.CmfzLogMapper;
import com.baizhi.cmfz.util.IPKit;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Aspect //声明这是一个切面类
@Configuration //声明这是一个配置类
public class LogAopAspect {

    @Autowired
    private CmfzLogMapper clm;

    /**
     * 日志增强
     * 1.获取日志信息
     * 2.日志数据添加到数据库中
     */
    @After("@annotation(com.baizhi.cmfz.annotation.LogAnnotation)")
    public void logAfter(JoinPoint joinPoint){
        CmfzLog cmfzLog = new CmfzLog();
        /**
         * 1 获取日志数据
         */
        //获取日期
        cmfzLog.setLogDate(new Date());
        //获取ip
        /**
         * RequestContextHolder 可以获取当前线程的请求
         * 一般情况下 ip获取会使用工具类
         */
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String ip = IPKit.getIpAddrByRequest(request);
        cmfzLog.setLogIp(ip);
        //获取用户名 session中的登录标识
        String username= (String)request.getSession().getAttribute("admin");
        if(username==null){
            cmfzLog.setUsername("root");
        }else{
            cmfzLog.setUsername(username);
        }
        //获取操作类型和操作内容
        /**
         * 通过joinPoint可以获取切入点附近所有的信息 类 方法 属性 注解
         等等
         *
         * 获取当前被切方法的日志注解
         * 1 通过连接点对象joinPoint获取 方法签名对象
         * 2 通过方法签名对象获取被切的方法
         * 3 通过方法对象获取方法上的注解
         * 4 获取注解中的值
         */
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        //参数是要获取的注解的类对象
        LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
        //赋值
        cmfzLog.setLogType(annotation.type());
        cmfzLog.setLogContent(annotation.value());

        /**
         * 日志数据添加到数据库
         */
        clm.insert(cmfzLog);
    }

}
